home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / libdemo / slider.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  439 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Definitions for slider bar routines.
  19.  * These work with the event-handling routines.
  20.  * Written by Thant Tessman, modified a bit by Gavin Bell,
  21.  * for Silicon Graphics
  22.  */
  23. #include <stdio.h>
  24. #include <gl.h>
  25. #include <get.h>
  26. #include <fmclient.h>
  27. #include <device.h>
  28. #include "slider.h"
  29. #include "event.h"
  30.  
  31. typedef struct slider_struct
  32. {
  33.     int  type;    /* SLIDER_INT or SLIDER_FLOAT */
  34.     long gid;    /* Window I'm in */
  35.     long displaymode;    /* And display mode */
  36.  
  37.     sliderval *val;    /* Current value */
  38.     float min, max;    /* Minimum and maximum value */
  39.  
  40.     float cornerx, cornery;    /* Corner coordinates */
  41.     long wcornerx, wcornery;    /* .. and in screen pixels */
  42.     long worx, wory;    /* Origin of window we're in */
  43.  
  44.     float sizex, sizey;    /* Size */
  45.     long wsizex, wsizey;    /* ... and in screen pixels */
  46.  
  47.     fmfonthandle fh, fh2;    /* Fonts from font manager */
  48.     float oldsize;    /* Size of fh2 */
  49.     char title[64];    /* Storage for slider title */
  50.  
  51.     int active;    /* Being moved? */
  52.  
  53.     void (*fn)();    /* Function to call when changes */
  54. } Slider;
  55.  
  56. /*
  57.  * Local function prototypes
  58.  */
  59. static void activate_slider(Slider *);
  60. static void deactivate_slider(Slider *);
  61. static void slider_resize(Slider *);
  62. static void adjust_slider(Slider *, int);
  63. static void save_winstuff(void);
  64. static void restore_winstuff(void);
  65. static void image_slot(Slider *), image_knob(Slider *);
  66.  
  67. char *
  68. add_slider(char *title, int type, float min, float max,
  69.     sliderval *variable, float cornerx, float cornery,
  70.     float sizex, float sizey, void (*fn)())
  71. {
  72.     long gid;
  73.     Slider *me;
  74.  
  75.     me = (Slider *) malloc(sizeof(Slider));
  76.  
  77.     memset((char *)me, (char)0, sizeof(Slider));
  78.  
  79.     me->type = type;
  80.     me->gid = gid = winget();
  81.     me->displaymode = getdisplaymode();
  82.     me->val = variable;
  83.     me->min = min; me->max = max;
  84.     me->active = FALSE;
  85.  
  86.     strncpy(me->title, title, 64);
  87.     
  88.     fminit();
  89.     me->fh = fmfindfont("Times-Roman");
  90.  
  91.     me->cornerx = cornerx;    me->cornery = cornery;
  92.     me->sizex = sizex;    me->sizey = sizey;
  93.     me->fn = fn;
  94.  
  95.     slider_resize(me);
  96.  
  97.     if (!isqueued(LEFTMOUSE)) qdevice(LEFTMOUSE);
  98.     add_event(gid, LEFTMOUSE, DOWN, activate_slider, (char *)me);
  99.     add_event(gid, LEFTMOUSE, UP, deactivate_slider, (char *)me);
  100.  
  101.     if (!isqueued(REDRAW)) qdevice(REDRAW);
  102.     add_event(ANY, REDRAW, gid, slider_resize, (char *)me);
  103.  
  104.     add_event(gid, MOUSEX, ANY, adjust_slider, (char *)me);
  105.  
  106.     return (char *)me;
  107. }
  108.  
  109. void
  110. draw_slider(char *t)
  111. {
  112.     long oldgid;
  113.     char str[100];
  114.     float length;
  115.     Slider *s;
  116.  
  117.     s = (Slider *)t;
  118.     save_winstuff();
  119.     oldgid = winget();
  120.     winset(s->gid);
  121.     viewport(s->wcornerx, s->wcornerx+s->wsizex-1,
  122.             s->wcornery, s->wcornery+s->wsizey-1);
  123.  
  124.     fmsetfont(s->fh2);
  125.  
  126.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  127.         RGBcolor(50, 50, 50);
  128.     else
  129.         color(36);
  130.     clear();
  131.     ortho2(-0.2, 1.2, -1.0, 2.0);
  132.  
  133.      switch (s->type)
  134.     {
  135.         case SLIDER_INT:
  136.             sprintf(str, s->title, (*s->val).i);
  137.             break;
  138.         case SLIDER_FLOAT:
  139.             sprintf(str, s->title, (*s->val).f);
  140.             break;
  141.     }
  142.     length = fmgetstrwidth(s->fh2, str);
  143.  
  144.     length = length * 1.4 / s->wsizex / 2.0;
  145.  
  146.     cmov2(0.5 - length, 1.0);
  147.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  148.         RGBcolor(255, 255, 255);
  149.     else
  150.         color(7);
  151.     fmprstr(str);
  152.  
  153.     image_slot(s);
  154.     
  155.      switch (s->type)
  156.     {
  157.         case SLIDER_INT:
  158.             translate(((float)(*s->val).i - s->min)/
  159.                 (s->max - s->min), 0.0, 0.0);
  160.             break;
  161.         case SLIDER_FLOAT:
  162.             translate(((*s->val).f - s->min)/
  163.                 (s->max - s->min), 0.0, 0.0);
  164.             break;
  165.     }
  166.     scale(0.01, 0.3, 1.0);
  167.     image_knob(s);
  168.  
  169.     winset(oldgid);
  170.     restore_winstuff();
  171. }
  172.  
  173. static void
  174. slider_resize(Slider *me)
  175. {
  176.     long oldgid;
  177.     long sx, sy;
  178.  
  179.     oldgid = winget();
  180.     winset(me->gid);
  181.     
  182.     getorigin(&me->worx, &me->wory);
  183.     getsize(&sx, &sy);
  184.  
  185.     me->wcornerx = sx*me->cornerx;
  186.     me->wcornery = sy*me->cornery;
  187.  
  188.     /* This is written this way to avoid off-by-one errors */
  189.     me->wsizex = sx*(me->cornerx+me->sizex) - me->wcornerx;
  190.     me->wsizey = sy*(me->cornery+me->sizey) - me->wcornery;
  191.  
  192.     {
  193.         float t;
  194.         t = (double) (me->wsizey) / 3.5;
  195.         if (me->fh2 == NULL || t != me->oldsize)
  196.         {
  197.             if (me->fh2 != NULL)
  198.                 fmfreefont(me->fh2);
  199.             me->fh2 = fmscalefont(me->fh, t);
  200.             me->oldsize = t;
  201.         }
  202.     }
  203.     if (me->displaymode == DMDOUBLE || me->displaymode == DMRGBDOUBLE)
  204.     {
  205.         draw_slider((char *)me);
  206.         swapbuffers();
  207.         draw_slider((char *)me);
  208.     }
  209.     else
  210.         draw_slider((char *)me);
  211.  
  212.     winset(oldgid);
  213. }
  214.  
  215. static Boolean mousexqueued;
  216.  
  217. static void
  218. activate_slider(Slider *s)
  219. {
  220.     int x, mx, my;
  221.  
  222.     x = getvaluator(MOUSEX);
  223.     mx = x - s->worx;
  224.     my = getvaluator(MOUSEY);
  225.     my = my - s->wory;
  226.  
  227.     if (mx < s->wcornerx || mx > s->wcornerx+s->wsizex
  228.         || my < s->wcornery || my > s->wcornery+s->wsizey)
  229.         return;
  230.  
  231.     mousexqueued = isqueued(MOUSEX);
  232.     if (!mousexqueued)
  233.     {
  234.         qdevice(MOUSEX);
  235.     }
  236.  
  237.     s->active = TRUE;
  238.     adjust_slider(s, x);
  239. }
  240.  
  241. static void
  242. deactivate_slider(Slider *s)
  243. {
  244.     long prev_window;
  245.  
  246.     if (s->active == FALSE) return;
  247.  
  248.     prev_window = winget();
  249.  
  250.     if (!mousexqueued)
  251.     {
  252.         unqdevice(MOUSEX);
  253.     }
  254.  
  255.     winset(s->gid);
  256.     
  257.     if (s->displaymode == DMDOUBLE || s->displaymode == DMRGBDOUBLE)
  258.     {
  259.         if (s->fn != NULL) s->fn(s);
  260.         draw_slider((char *)s);
  261.         swapbuffers();
  262.         if (s->fn != NULL) s->fn(s);
  263.         draw_slider((char *)s);
  264.     }
  265.     s->active = FALSE;
  266.  
  267.     winset(prev_window);
  268. }
  269.  
  270. static void
  271. adjust_slider(Slider *s, int mx)
  272. {
  273.     float oldval, newval;
  274.     long oldgid;
  275.  
  276.     if (s->active == FALSE) return;
  277.  
  278.     mx = mx - s->worx;
  279.  
  280.     if (s->type == SLIDER_INT)
  281.         oldval = (float) (*s->val).i;
  282.     else oldval = (*s->val).f;
  283.  
  284.     /* This scales from 0.0 to 1.0 */
  285.     newval = ((mx - s->wcornerx) * 1.4 / s->wsizex) - 0.2;
  286.  
  287.     /* And this scales from min to max */
  288.     newval= s->min + newval*(s->max - s->min);
  289.  
  290.     if (newval < s->min) newval = s->min;
  291.     if (newval > s->max) newval = s->max;
  292.  
  293.     if (s->type == SLIDER_INT) newval = (float)((int)newval);
  294.  
  295.     if (oldval != newval)
  296.     {
  297.         if (s->type == SLIDER_INT)
  298.             (*s->val).i = (int)newval;
  299.         else
  300.             (*s->val).f = newval;
  301.  
  302.         oldgid = winget();
  303.         winset(s->gid);
  304.  
  305.         if (s->fn != NULL) s->fn(s);
  306.         draw_slider((char *)s);
  307.         swapbuffers();
  308.  
  309.         winset(oldgid);
  310.     }
  311. }
  312.  
  313. /*
  314.  * This routine figures out what matrix mode we're in, and
  315.  * saves the relevant matrices.  It then puts an identity matrix on
  316.  * top of the VIEWING or SINGLE stack, and also saves the viewport.
  317.  * When exiting, the matrix state will be in MVIEWING or MSINGLE
  318.  */
  319. static Matrix idmatrix =
  320. {
  321.     1., 0., 0., 0.,
  322.     0., 1., 0., 0.,
  323.     0., 0., 1., 0.,
  324.     0., 0., 0., 1.,
  325. };
  326.  
  327. static int lastmode;
  328.  
  329. static void
  330. save_winstuff()
  331. {
  332.     lastmode = getmmode();
  333.     if (lastmode == MSINGLE)
  334.     {
  335.         pushmatrix();
  336.         loadmatrix(idmatrix);
  337.     }
  338.     else
  339.     {
  340.         Matrix m;
  341.  
  342.         mmode(MPROJECTION);
  343.         getmatrix(m);
  344.         mmode(MVIEWING);
  345.         pushmatrix();    /* Stack is:  Viewing */
  346.         loadmatrix(m);    /* .........  Projection */
  347.         pushmatrix();    /* .........  Identity */
  348.         loadmatrix(idmatrix);
  349.     }
  350.     pushviewport();
  351. }
  352.  
  353. static void
  354. restore_winstuff()
  355. {
  356.     popviewport();
  357.  
  358.     if (lastmode == MSINGLE)
  359.     {
  360.         popmatrix();
  361.     }
  362.     else
  363.     {
  364.         Matrix m;
  365.  
  366.         popmatrix();
  367.         getmatrix(m);    /* Projection matrix */
  368.         mmode(MPROJECTION);
  369.         loadmatrix(m);
  370.         mmode(MVIEWING);
  371.         popmatrix();    /* Viewing back */
  372.         mmode(lastmode);    /* And put mode back */
  373.     }
  374. }
  375.  
  376. static void
  377. image_slot(Slider *s)
  378. {
  379.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  380.         RGBcolor(0, 0, 255);
  381.     else
  382.         color(4);
  383.     rectf(0.0, -0.2, 1.0, 0.2);
  384.  
  385.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  386.         RGBcolor(255, 255, 0);
  387.     else
  388.         color(3);
  389.     rect(0.0, -0.2, 1.0, 0.2);
  390. }
  391.  
  392. static void
  393. image_knob(Slider *s)
  394. {
  395.     rotate(450, 'z');
  396.  
  397.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  398.         RGBcolor(240, 240, 240);
  399.     else
  400.         color(54);
  401.     pmv2i(-2, -2);
  402.     pdr2i(-1, -1);
  403.     pdr2i(-1, 1);
  404.     pdr2i(-2, 2);
  405.     pclos();
  406.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  407.         RGBcolor(200, 200, 200);
  408.     else
  409.         color(51);
  410.     pmv2i(-2, 2);
  411.     pdr2i(-1, 1);
  412.     pdr2i(1, 1);
  413.     pdr2i(2, 2);
  414.     pclos();
  415.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  416.         RGBcolor(150, 150, 150);
  417.     else
  418.         color(46);
  419.     pmv2i(2, 2);
  420.     pdr2i(1, 1);
  421.     pdr2i(1, -1);
  422.     pdr2i(2, -2);
  423.     pclos();
  424.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  425.         RGBcolor(130, 130, 130);
  426.     else
  427.         color(44);
  428.     pmv2i(2, -2);
  429.     pdr2i(1, -1);
  430.     pdr2i(-1, -1);
  431.     pdr2i(-2, -2);
  432.     pclos();
  433.     if (s->displaymode == DMRGB || s->displaymode == DMRGBDOUBLE)
  434.         RGBcolor(170, 170, 170);
  435.     else
  436.         color(48);
  437.     rectfi(-1, -1, 1, 1);
  438. }
  439.